//////////////////////////////////////////////
// UserType.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkScripts
{
	class Function ;

	struct ArrayAccessorDescriptor ;
	struct UserTypeFieldDescriptor ;
}

/// Includes ---------------------------------

// nkScripts
#include "../../Dll/DllDefines.h"

#include "../Functions/FunctionDefines.h"

#include "TypeBuiltInFunctions.h"

// nkMemory
#include <NilkinsMemory/Containers/String.h>
#include <NilkinsMemory/Containers/StringView.h>

// Standards
#include <functional>

/// Internals --------------------------------

namespace nkScripts
{
	using ConstructorCallback = std::function<void*(const DataStack&)> ;
	using DestructorCallback = std::function<void(void*)> ;
}

/// Class ------------------------------------

namespace nkScripts
{
	class DLL_SCRIPTS_EXPORT UserType
	{
		public :

			// Constructeur, destructeur
			UserType (nkMemory::StringView name) noexcept ;
			virtual ~UserType () ;

			// Getters
			nkMemory::StringView getName () const ;
			nkMemory::StringView getFullName () const ;
			virtual Function* getMethod (nkMemory::StringView name) = 0 ;
			virtual Function* getStaticMethod (nkMemory::StringView name) = 0 ;

			// Contrôles sur le user type
			virtual void setConstructor (ConstructorCallback constructor) = 0 ;
			virtual void setDestructor (DestructorCallback destructor) = 0 ;
			virtual Function* addMethod (nkMemory::StringView name, bool strongReferenceOverThis = false) = 0 ;
			virtual Function* addStaticMethod (nkMemory::StringView name) = 0 ;
			virtual Function* overrideBuiltInFunction (TYPE_BUILT_IN_FUNCTIONS builtInFunc) = 0 ;
			virtual void addField (const UserTypeFieldDescriptor& fieldDescriptor) = 0 ;
			virtual void enableArrayIndexing (const ArrayAccessorDescriptor& descriptor) = 0 ;
			virtual void reset () = 0 ;

		protected :

			// Attributes
			// Nom du type
			nkMemory::String _name ;
			// Fully qualified dans le namespace ou autre
			nkMemory::String _fullName ;
	} ;
}